package com.rocky.pubimport.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Date;

/**
 * mybatisplus 自动填充
 * @author rocky
 * @date 2022/4/13 10:25
 */
@Component
public class MyBatisMetaObjectHandler implements MetaObjectHandler {

    private static final String CREATE_TIME = "createdTime";
    private static final String UPDATE_TIME = "updatedTime";

    /**
     * 新增数据执行
     * @param metaObject 元数据对象
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        autoInsertTime(metaObject, CREATE_TIME);
        autoInsertTime(metaObject, UPDATE_TIME);
    }

    /**
     * 更新数据执行
     * @param metaObject 元数据对象
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        autoInsertTime(metaObject, UPDATE_TIME);
    }

    /**
     * 判断是否有时间字段，如果有就插入当前时间
     * @param metaObject 元数据对象
     * @param time 时间
     */
    private void autoInsertTime(MetaObject metaObject, String time) {
        if (metaObject.hasSetter(time) && metaObject.hasGetter(time)) {
            setFiledValue(metaObject, time);
        } else if (metaObject.hasGetter("et")) {
            Object et = metaObject.getValue("et");
            if (et != null) {
                MetaObject etMeta = SystemMetaObject.forObject(et);
                if (etMeta.hasSetter(time)) {
                    setFiledValue(etMeta, time);
                }
            }
        }
    }

    /**
     * 填充字段
     *
     * @param metaObject metaObject 对象
     * @param time       字段值
     */
    private void setFiledValue(MetaObject metaObject, String time) {
        Class createTimeClassType = metaObject.getGetterType(time);
        Object timeObj = getDateTimeObj(createTimeClassType);
        if (timeObj != null) {
            metaObject.setValue(time, timeObj);
        }
    }

    /**
     * 根据字段类型判断用哪种方式赋值时间，String类型忽略
     *
     * @param classType 字段类型class
     * @return 时间
     */
    private Object getDateTimeObj(Class classType) {
        Object now = null;
        if (classType == Date.class) {
            now = new Date();
        } else if (classType == LocalDateTime.class) {
            now = LocalDateTime.now();
        }
        return now;
    }

}
